﻿using Microsoft.Practices.Unity;
using PagedList;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tippelde.Services.Bets;
using Tippelde.Services.Dtos;
using Tippelde.Services.Events;
using Tippelde.Services.Exceptions;
using Tippelde.Services.Groups;
using Tippelde.Web.Helpers;
using Tippelde.Web.Models.Event;
using Tippelde.Web.Models.Group;

namespace Tippelde.Web.Controllers
{
    [Authorize]
    public class EventController : Controller
    {

        [Dependency]
        public IGroupManager GroupManager { get; set; }

        [Dependency]
        public IEventManager EventManager { get; set; }

        [Dependency]
        public IBetManager BetManager { get; set; }

        public ActionResult Index(int? page)
        {
            var model = new EventListModel
            {
                HasAnyEditorRights = CacheManager.Current.UserHasAnyEditorRights(),
                Events = EventManager.GetEventHeadersWithBetForUser(User.Identity.Name, page),
                Groups = CacheManager.Current.GetGroupsForUser()
            };

            return View(model);
        }

        public ActionResult Group(int Id, int? page)
        {
            var model = new EventListModel
            {
                HasAnyEditorRights = CacheManager.Current.UserHasAnyEditorRights(Id),
                Events = EventManager.GetEventHeadersWithBet(User.Identity.Name, Id, page),
                Groups = CacheManager.Current.GetGroupsForUser()
            };
            ViewBag.SelectedGroupId = Id;
            return View("Index", model);
        }

        public ActionResult Create()
        {
            ViewBag.Action = "Create";
            var model = new CreateEventModel()
            {
                GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }
                ).ToList()
            };
            return View("Editor", model);
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(CreateEventModel model)
        {
            ViewBag.Action = "Create";
            var editableGroupIds = CacheManager.Current.GetGroupIdsForEditor();
            foreach (var key in new List<int>(model.Groups.Keys))
            {
                if (!editableGroupIds.Contains(key))
                {
                    model.Groups.Remove(key);
                }
            }

            if (model.Groups.Count(kv => kv.Value == true) < 1)
            {
                ModelState.AddModelError("", "Nincs csoport kiválasztva");
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }).ToList();
                return View("Editor", model);
            }

            if (!ModelState.IsValid)
            {
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            EventHeaderData ehd = new EventHeaderData()
            {
                Name = model.EventName,
                ShortName = model.ShortName,
                Description = model.Description,
                HomeTeam = new TeamHeaderData { Id = model.HomeTeamId },
                AwayTeam = new TeamHeaderData { Id = model.AwayTeamId },
                Status = model.Status,
                EventDate = model.EventDate.Value//.Add(model.EventDateOffset.Value)
            };
            if (model.BetStartAt.HasValue)
            {
                ehd.BetStartAt = model.BetStartAt.Value;//.Add(model.BetStartAtOffset ?? new TimeSpan());
            }
            if (model.BetEndAt.HasValue)
            {
                ehd.BetEndAt = model.BetEndAt.Value;//.Add(model.BetEndAtOffset ?? new TimeSpan());
            }
            try
            {
                var groupIds = model.Groups.Where(i => i.Value).Select(i => i.Key);
                EventManager.CreateEvent(ehd, User.Identity.Name, groupIds);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            return RedirectToAction("Index");
        }


        public ActionResult Edit(int Id)
        {
            ViewBag.Action = "Edit";
            if (!GroupManager.HasAnyEditorRightsForEvent(User.Identity.Name, Id))
            {
                return RedirectToAction("Index");
            }
            var e = EventManager.GetEventHeader(Id);
            var containingGroups = GroupManager.GetActiveGroupIdsForEvent(Id);
            var model = new CreateEventModel()
            {
                GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = containingGroups.Contains(g.Id),
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }
                ).ToList(),
                Id = e.Id,
                AwayTeamId = e.AwayTeam.Id,
                HomeTeamId = e.HomeTeam.Id,
                HomeTeamName = String.Format("{0} ({1})", e.HomeTeam.Name, e.HomeTeam.ShortName),
                AwayTeamName = String.Format("{0} ({1})", e.AwayTeam.Name, e.AwayTeam.ShortName),
                BetStartAt = e.BetStartAt,
                BetEndAt = e.BetEndAt,
                EventDate = e.EventDate,
                Description = e.Description,
                EventName = e.Name,
                ShortName = e.ShortName,
                Status = e.Status
            };
            return View("Editor", model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(CreateEventModel model)
        {
            ViewBag.Action = "Edit";
            if (!GroupManager.HasAnyEditorRightsForEvent(User.Identity.Name, model.Id))
            {
                return RedirectToAction("Index");
            }
            var editableGroupIds = CacheManager.Current.GetGroupIdsForEditor();
            foreach (var key in new List<int>(model.Groups.Keys))
            {
                if (!editableGroupIds.Contains(key))
                {
                    model.Groups.Remove(key);
                }
            }
            if (!ModelState.IsValid)
            {
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            if (model.Groups.Count(kv => kv.Value == true) < 1)
            {
                ModelState.AddModelError("", "Nincs csoport kiválasztva");
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName,
                 }).ToList();
                return View("Editor", model);
            }
            EventHeaderData ehd = new EventHeaderData()
            {
                Id = model.Id,
                Name = model.EventName,
                ShortName = model.ShortName,
                Description = model.Description,
                HomeTeam = new TeamHeaderData { Id = model.HomeTeamId },
                AwayTeam = new TeamHeaderData { Id = model.AwayTeamId },
                Status = model.Status,
                EventDate = model.EventDate.Value
            };
            if (model.BetStartAt.HasValue)
            {
                ehd.BetStartAt = model.BetStartAt.Value;
            }
            if (model.BetEndAt.HasValue)
            {
                ehd.BetEndAt = model.BetEndAt.Value;
            }
            try
            {
                var groupIds = model.Groups.Where(i => i.Value).Select(i => i.Key);
                EventManager.EditEvent(ehd, User.Identity.Name, groupIds);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
                model.GroupList = CacheManager.Current.GetGroupsForEditor().Select(
                 g => new SelectableGroupHeaderData
                 {
                     Id = g.Id,
                     IsSelected = false,
                     Name = g.Name,
                     ShortName = g.ShortName
                 }).ToList();
                foreach (var item in model.Groups)
                {
                    if (!item.Value)
                        continue;
                    var group = model.GroupList.SingleOrDefault(g => g.Id == item.Key);
                    if (group != null)
                    {
                        group.IsSelected = true;
                    }
                }
                return View("Editor", model);
            }
            return RedirectToAction("Index");
        }

        public ActionResult ResultAdd(EventWithBetData model)
        {
            if (model == null || model.Result == null)
            {
                ModelState.AddModelError("", "Hiba az eredmény beolvasása közben");
                return Row(model.Id);
            }
            if (!GroupManager.HasAnyEditorRightsForEvent(User.Identity.Name, model.Id))
            {
                ModelState.AddModelError("", "Nincs jogod módosítani!");
                model.IsUserEditor = false;
                return Row(model.Id);
            }
            if (model.Result.HomeResult < 0 || model.Result.AwayResult < 0)
            {
                ModelState.AddModelError("", "Eredmény nem lehet negatív");
                return Row(model.Id);
            }
            try
            {
                BetManager.AddResultAndCheckBets(User.Identity.Name, model.Id, model.Result);
                model.HasResult = true;
                model.IsUserEditor = true;
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
            }
            return Row(model.Id);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Delete(int Id)
        {
            if(GroupManager.HasAnyEditorRightsForEvent(User.Identity.Name, Id))
            {
                EventManager.DeleteEvent(Id);
            }
            return RedirectToAction("Index");
        }

        public ActionResult ResultDelete(EventWithBetData model)
        {
            if (model == null || model.Result == null)
            {
                ModelState.AddModelError("", "Hiba az eredmény beolvasása közben");
                return Row(model.Id);
            }
            if (!GroupManager.HasAnyEditorRightsForEvent(User.Identity.Name, model.Id))
            {
                ModelState.AddModelError("", "Nincs jogod módosítani!");
                model.IsUserEditor = false;
                return Row(model.Id);
            }
            try
            {
                BetManager.DeleteResultAndRevertBetResults(User.Identity.Name, model.Id);
                model.HasResult = false;
                model.IsUserEditor = true;
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", ex);
            }
            return Row(model.Id);
        }

        public ActionResult Details(int Id)
        {
            var model = new EventListModel
            {
                Events = new List<EventWithBetData>() { 
                    EventManager.GetEventHeaderWithBet(User.Identity.Name, Id)
                }.ToPagedList(1, 1),
                Groups = CacheManager.Current.GetGroupsForUser(),
                HasAnyEditorRights = false
            };
            return View("Index", model);
        }


        public ActionResult Row(int Id)
        {
            var model = EventManager.GetEventHeaderWithBet(User.Identity.Name, Id);
            var state = TempData["ModelState"] as ModelStateDictionary;
            if (state != null)
                ModelState.Merge(state);
            return PartialView("_EventRow", model);
        }
    }
}